Miami evened its road trip at 2-2 after dropping two straight at Arizona, and Koehler celebrated his first big league win.
"It's definitely pretty nice," the Bronx, N.Y., native said. "They're a great ballclub over there. They fought hard, just like we did. Luckily, we came out on top."
Steve Cishek worked around a one-out single to Buster Posey in the ninth inning and recorded his 11th save, which also gave the Marlins their eighth straight victory at AT&T Park.
"It was nice for us to get that big hit and score a couple of runs, and get him that first win," Marlins manager Mike Redmond said. "It was pretty cool."
The Marlins grabbed the lead in the eighth on Ozuna's single. Pinch-hitting for the first time in his career, the 22-year-old slapped Jeremy Affeldt's 0-2 offering into right field.
Before his pinch-hit appearance, Ozuna was in a 2-for-33 rut, including 1-for-11 on the road trip.
The rookie had a simple approach. If Affeldt pitched him in, he was going to try to turn and drive the ball. If the pitch was away, he was prepared to poke the ball the other way.
"If he throws me in, I'm going to hit a home run," Ozuna said. "I'm going to swing hard. If he threw me away, I was going to throw my bat. That's what happened, he threw me away. I got a base hit to right field."
An elated Koehler gave Ozuna a big hug in the dugout.
"He said to me, 'Thank you.' I said, 'Congratulations, papa!'" Ozuna said. "It was his first win. He was happy. He did good today, just one run in seven innings. No-hitter for 5 1/3. That was a good game today."
Making his ninth career start and appearing in his 22nd big league game, Koehler finally had his first win.
"It didn't weigh on my confidence, but to say I didn't think about it would be a lie," Koehler said of his winless streak. "Every time I went out there, I wanted to win the game. I was wondering what it would take to do it. I actually thought it would be a game like last game when we were hit around a little bit.
"I thought it would be one of those weird-type games. Just the way the team battled back is phenomenal. It speaks to the character of this team. We've battled like that all year, and now it's starting to pay off."
Afterwards, Koehler was doused by a beverage he said made him "smell like a bar." To honor his first victory, the right-hander got the game ball from Cishek.
"That one stays with me," Koehler said. "It's going to go in a nice little case and go somewhere in my man cave at home. I gave my first-hit ball to my dad. This one is staying with me.
"Cishek gave it to me. I'm glad that he did. I was going to chase him down if he didn't."
The right-hander carried a no-hitter into the sixth inning before giving up a one-out single to right to Gregor Blanco.
"He had good stuff basically," Giants first baseman Brandon Belt said. "He located well enough to get us out, but it was basically his stuff. He did enough to keep us to one run."
In the third inning, Koehler benefited from a terrific sliding catch by Justin Ruggiano in center field. Ruggiano dashed in and corralled Blanco's sinking liner.
An inning after his no-hit bid was erased, so was Koehler's shutout bid. With two outs in the seventh inning, the Giants used back-to-back extra-base hits to take a 1-0 lead. Belt doubled and scored on Joaquin Arias' triple.
The Marlins were held to two hits heading into the eighth.
Giants starter Chad Gaudin, a Marlins reliever in 2012, was cruising until the fifth inning when he exited after being struck on the right elbow by a comeback shot off Derek Dietrich's bat.
Gaudin was able to stay on the play, and he threw Dietrich out at first. But the veteran was in pain and was tended to by the Giants' training staff and manager Bruce Bochy.
Gaudin threw a couple of warmup pitches, but he was replaced by Sandy Rosario, another former Marlin.
Neither team mounted much offense, as the Marlins finished with five hits with Ozuna's being the only one in the eighth inning. The Giants tallied just four hits.
"Give [Ozuna] credit," Bochy said. "He reached out and did a good piece of hitting."